

#pragma  once
#ifndef _OCAF_HEADER_
#define _OCAF_HEADER_

#include <TDocStd_Document.hxx>
#include <TPrsStd_AISViewer.hxx>
#include <TDF_Label.hxx>
#include <TDF_Reference.hxx>
#include <TDF_ChildIterator.hxx>
#include <TNaming_NamedShape.hxx>
#include <TNaming_Builder.hxx>
#include <TDataStd_Real.hxx>
#include <TFunction_Logbook.hxx>
#include <TPrsStd_AISPresentation.hxx>
#include <TDataStd_Name.hxx>
#include <TFunction_DriverTable.hxx>
#include <TFunction_Function.hxx>
#include <TDataStd_Integer.hxx>
#include <Standard_GUID.hxx>
#include <TFunction_Driver.hxx>

/************************************************************************/
/* Function driver memory management                                    */
/************************************************************************/
#define FUNCTONDRIVER_MEMORY_MGR(functionDriver) \
	public:\
		inline void* operator new(size_t,void* anAddress) \
		{\
			return anAddress;\
		}\
		inline void* operator new(size_t size) \
		{ \
			return Standard::Allocate(size); \
		}\
		inline void  operator delete(void *anAddress) \
		{ \
			if (anAddress) Standard::Free((Standard_Address&)anAddress); \
		}\
		\
		Standard_EXPORT friend Handle_Standard_Type& functionDriver##_Type_();\
		Standard_EXPORT const Handle(Standard_Type)& DynamicType() const;\
		Standard_EXPORT Standard_Boolean	       IsKind(const Handle(Standard_Type)&) const;\

/************************************************************************/
/* declare the handle of function driver                                */
/************************************************************************/
#define DECLARE_FUNCTIONDRIVER_HANDLE(functionDriver) \
	Standard_EXPORT Handle_Standard_Type& STANDARD_TYPE(functionDriver);\
	\
	class Handle(functionDriver) : public Handle(TFunction_Driver)\
	{\
	public:\
		inline void* operator new(size_t,void* anAddress)\
		{\
			return anAddress;\
		}\
		inline void* operator new(size_t size) \
		{ \
			return Standard::Allocate(size); \
		}\
		inline void  operator delete(void *anAddress) \
		{ \
			if (anAddress) Standard::Free((Standard_Address&)anAddress); \
		}\
		\
		Handle(functionDriver)():Handle(TFunction_Driver)() {} \
		Handle(functionDriver)(const Handle(functionDriver)& aHandle) : Handle(TFunction_Driver)(aHandle) \
		{\
		}\
		\
		Handle(functionDriver)(const functionDriver* anItem) : Handle(TFunction_Driver)((TFunction_Driver *)anItem) \
		{\
		}\
		\
		Handle(functionDriver)& operator=(const Handle(functionDriver)& aHandle)\
		{\
			Assign(aHandle.Access());\
			return *this;\
		}\
		\
		Handle(functionDriver)& operator=(const functionDriver* anItem)\
		{\
			Assign((Standard_Transient *)anItem);\
			return *this;\
		}\
		\
		functionDriver* operator->() \
		{\
			return (functionDriver *)ControlAccess();\
		}\
		\
		functionDriver* operator->() const \
		{\
			return (functionDriver *)ControlAccess();\
		}\
		\
		Standard_EXPORT ~Handle(functionDriver)();\
		\
		Standard_EXPORT static const Handle(functionDriver) DownCast(const Handle(Standard_Transient)& AnObject);\
	};\


/************************************************************************/
/* implement the handle of function driver                              */
/************************************************************************/

#define IMPLEMENT_FUNCTIONDRIVER_HANDLE(functionDriver) \
	\
	Standard_EXPORT Handle_Standard_Type& functionDriver##_Type_()\
	{\
	\
		static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);\
		if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);\
		static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);\
		if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);\
		static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);\
		if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);\
	\
		static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};\
		static Handle_Standard_Type _aType = new Standard_Type(#functionDriver,\
			sizeof(functionDriver),\
			1,\
			(Standard_Address)_Ancestors,\
			(Standard_Address)NULL);\
	\
		return _aType;\
	}\
	\
	const Handle(functionDriver) Handle(functionDriver)::DownCast(const Handle(Standard_Transient)& AnObject) \
	{\
		Handle(functionDriver) _anOtherObject;\
	\
		if (!AnObject.IsNull()) {\
			if (AnObject->IsKind(STANDARD_TYPE(functionDriver))) {\
				_anOtherObject = Handle(functionDriver)((Handle(functionDriver)&)AnObject);\
			}\
		}\
	\
		return _anOtherObject ;\
	}\
	const Handle(Standard_Type)& functionDriver::DynamicType() const \
	{ \
		return STANDARD_TYPE(functionDriver) ; \
	}\
	Standard_Boolean functionDriver::IsKind(const Handle(Standard_Type)& AType) const \
	{ \
		return (STANDARD_TYPE(functionDriver) == AType || TFunction_Driver::IsKind(AType)); \
	}\
	\
	Handle(functionDriver)::~Handle_##functionDriver() {}\




#endif